Many software applications, such as video games, include a file input/output (I/O) scheduler to make media access within an application more efficient and reliable. A file I/O system (FIOS) is a middleware layer for accessing files with several parts including a scheduler and optional I/O filter layers. The scheduler is typically designed to optimally sort I/O requests so that they complete in the shortest possible time subject to arbitrary deadline and priority constraints. The filter layers may provide additional services such as decompression or caching.
Many different game components require I/O access to files in storage media. Audio components load audio files; game-play engines load level definitions; graphics components load texture maps and models; movie components load audio-visual files; and subsystems load large WAD files. The media may be game-delivery media such as optical discs (universal media disc (UMD), compact disc (CD), digital video disc (DVD), Blu-Ray disc, etc.), intermediate storage media such as hard disks, or other media types as platforms evolve.
A single application, such as a video game, typically has multiple components, each component having its own I/O requirements. Some require streaming access to media, where the I/O system streams data in the file to the component so the component can present the streamed data in succession to the game player. For example, an audio component typically streams an audio file for soundtrack playback; a movie component streams audio-video content to play back a movie for the player. Other components need only non-streaming access where they retrieve data from the file in portions, referred to herein as chunks, for the component to process. Although these components do not require steady data flow in order to process, timing of the delivery of the chunks is often crucial. If an application doesn't receive data when it is needed, performance may suffer.
Currently, chunking (i.e., breaking data for an I/O request into portions/chunks) occurs during execution of the I/O request. Data dependencies between chunks are not determined prior to execution, and this leads to inefficiencies in the processing of I/O requests. For example, a given I/O request may require data that needs to be both decrypted and decompressed before transfer. The I/O system may require that decryption of a given chunk occur before decompression, but different chunk sizes may be associated with decryption and decompression. For example, the chunk sizes associated with decryption may have a fixed value such as 64 Kilobytes, whereas the chunk sizes associated with decompression may be variable. Thus, without determining the data dependencies between the chunks being decrypted and the chunks being decompressed, an entire file must be decrypted before the file can be decompressed, rather than initiating decompression of a given chunk once the necessary decrypted chunks have been processed.
Similarly, a given I/O request that requires data to be retrieved from multiple media sources may be processed inefficiently with the current form of chunking during execution. Without determining the data dependencies between chunks prior to execution, a media device may sit idle while data from another media device is being processed, when it is theoretically possible for data from both media devices to be processed simultaneously. This ultimately slows down the functionality of a video game or other application.
Furthermore, video games often perform a considerable amount of I/O. Game events are often time driven with deadlines that must be met. For example, if a player is traveling from point A to point B, the game needs to have the files for data associated with point B loaded before the player gets there. Game components can use low-level I/O primitives to retrieve data from media, but these primitives don't handle device contention when multiple components require data from the same device at the same time. Jammed-up I/O requests can interrupt streaming data flow or prohibit critical data chunks from getting to a component when needed.
Because an application's components typically are not aware of each other's I/O activities, their I/O requests often result in highly inefficient I/O patterns with a substantial amount of overseeking (back and forth searches for data). As games grow larger, overseeking and inefficient data retrieval increase.
It is within this context that embodiments of the present invention arise.